package se.mbaeumer.fxtodo.core.model;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

import se.mbaeumer.fxtodo.core.util.constants.ValueConstants;

import javafx.beans.property.IntegerProperty;
import javafx.beans.property.Property;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;

public class Task {
	private IntegerProperty id = new SimpleIntegerProperty(this, "id");
	private StringProperty title = new SimpleStringProperty(this, "title");
	private StringProperty description = new SimpleStringProperty(this, "description");
	private Property<Date> created = new SimpleObjectProperty<Date>();
	private StringProperty createdString = new SimpleStringProperty(this, "createdString");
	private Property<Date> dueDate = new SimpleObjectProperty<Date>();	
	private StringProperty dueDateString = new SimpleStringProperty(this, "dueDateString");
	private Property<TaskType> taskType = new SimpleObjectProperty<TaskType>();
	private Property<EnumTaskStatus> status = new SimpleObjectProperty<EnumTaskStatus>();
	private Property<Context> taskContext = new SimpleObjectProperty<Context>();
	private Property<EnumPriority> priority = new SimpleObjectProperty<EnumPriority>();
	
	public IntegerProperty idProperty(){return this.id;}
	public int getId(){return this.id.get();}
	public void setId(int id){this.id.set(id);}
	
	public StringProperty titleProperty(){return this.title;}
	public String getTitle(){return this.title.get();}
	public void setTitle(String title){this.title.set(title);}
	
	public StringProperty descriptionProperty(){return this.description;}
	public String getDescription(){return this.description.get();}
	public void setDescription(String description){this.description.set(description);}
	
	public Property<Date> createdProperty(){return this.created;}
	public Date getCreated(){return this.created.getValue();}
	public void setCreated(Date created){this.created.setValue(created);}
	
	public StringProperty createdStringProperty(){return this.createdString;}
	public String getCreatedString(){return this.createdString.get();}
	public void setCreatedString(String createdString){this.createdString.set(createdString);}
	
	public Property<Date> dueDateProperty(){return this.dueDate;}
	public Date getDueDate(){return this.dueDate.getValue();}
	public void setDueDate(Date dueDate){this.dueDate.setValue(dueDate);}
	
	public StringProperty dueDateStringProperty(){return this.dueDateString;}
	public String getDueDateString(){return this.dueDateString.get();}
	public void setDueDateString(String dueDateString){this.dueDateString.set(dueDateString);}
	
	public Property<TaskType> taskTypeProperty(){return this.taskType;}
	public TaskType getTaskType(){return this.taskType.getValue();}
	public void setTaskType(TaskType taskType){this.taskType.setValue(taskType);}
	
	public Property<EnumTaskStatus> taskStatusProperty(){return this.status;}
	public EnumTaskStatus getStatus(){return this.status.getValue();}
	public void setStatus(EnumTaskStatus status){this.status.setValue(status);}
	
	public Property<Context> taskContextProperty(){return this.taskContext;}
	public Context getTaskContext(){return this.taskContext.getValue();}
	public void setTaskContext(Context context){this.taskContext.setValue(context);}
	
	public Property<EnumPriority> priorityStatusProperty(){return this.priority;}
	public EnumPriority getPriority(){return this.priority.getValue();}
	public void setPriority(EnumPriority priority){this.priority.setValue(priority);}
	
	public static class TaskBuilder{
		
		private int id;
		private String title;
		private String description;
		private Date created;
		private Date dueDate;
		private EnumTaskStatus status;
		private TaskType taskType;
		private Context taskContext;
		private EnumPriority priority;

		public TaskBuilder id (int value){
			this.id = value;
			return this;
		}
		
		public TaskBuilder title (String value){
			title = value;
			return this;
		}
		
		public TaskBuilder description(String value){
			if (value == null){
				//TODO: Use constants instead of hard-coded strings
				value=ValueConstants.VALUE_N_A;
			}
			description = value;
			return this;
		}
		
		public TaskBuilder created (Date value){
			created = value;
			return this;
		}
		
		public TaskBuilder dueDate (Date value){
			dueDate = value;
			return this;
		}
		
		public TaskBuilder status (EnumTaskStatus value){
			status = value;
			return this;
		}
		
		public TaskBuilder taskType (TaskType value){
			taskType = value;
			return this;
		}
		
		public TaskBuilder taskContext (Context value){
			taskContext = value;
			return this;
		}
		
		public TaskBuilder priority (EnumPriority value){
			priority = value;
			return this;
		}
		
		public Task build(){
			return new Task(this);
		}
	}
	
	private Task(TaskBuilder taskBuilder){
		this.dueDate.addListener(new ChangeListener<Date>(){

			@Override
			public void changed(ObservableValue<? extends Date> arg0,
					Date arg1, Date arg2) {
				// TODO Auto-generated method stub
				updateDueDateString(arg2);
			}
			
		});
		
		this.created.addListener(new ChangeListener<Date>(){

			@Override
			public void changed(ObservableValue<? extends Date> arg0,
					Date arg1, Date arg2) {
				// TODO Auto-generated method stub
				updateCreatedString(arg2);
			}
			
		});
		
		this.id.set(taskBuilder.id);
		this.title.set(taskBuilder.title);
		this.description.set(taskBuilder.description);
		this.created.setValue(taskBuilder.created);
		this.dueDate.setValue(taskBuilder.dueDate);
		this.status.setValue(taskBuilder.status);
		this.taskType.setValue(taskBuilder.taskType);
		this.taskContext.setValue(taskBuilder.taskContext);
		this.priority.setValue(taskBuilder.priority);		
		//Context c = new Context.ContextBuilder().title("test").build();
		//this.dueDate = (Property<Date>) new Date(new SimpleDateFormat("dd/MM/yyyy HH:mm:ss").format(this.dueDate.getValue()));
	}
	
	private void updateDueDateString(Date dueDate){
		// TODO: Use constants instead of hard-coded strings
		DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm");
		this.setDueDateString(df.format(dueDate));
				
	}
	
	private void updateCreatedString(Date created){
		// TODO: Use constants instead of hard-coded strings
		DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm");
		this.setCreatedString(df.format(created));
	}
	
	/*public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getTitle() {
		return title;
	}
	public void setTitle(String title) {
		this.title = title;
	}
	public String getDescription() {
		return description;
	}
	public void setDescription(String description) {
		this.description = description;
	}
	public Date getCreated() {
		return created;
	}
	public void setCreated(Date created) {
		this.created = created;
	}
	public Date getDueDate() {
		return dueDate;
	}
	public void setDueDate(Date dueDate) {
		this.dueDate = dueDate;
	}
	public TaskStatus getStatus() {
		return status;
	}
	public void setStatus(TaskStatus status) {
		this.status = status;
	}
	public TaskType getTaskType() {
		return taskType;
	}
	public void setTaskType(TaskType taskType) {
		this.taskType = taskType;
	}
	public Context getTaskContext() {
		return taskContext;
	}
	public void setTaskContext(Context taskContext) {
		this.taskContext = taskContext;
	}*/
}
